package com.sokobanboxpro.game.gameplay;

import com.sokobanboxpro.game.entity.Move;
import com.sokobanboxpro.game.exception.ConfigValueNotFoundException;
import com.sokobanboxpro.game.managers.LevelManager;
import com.sokobanboxpro.game.system.Config;
import java.io.*;
import java.util.ArrayList;
import org.newdawn.slick.SlickException;

/**
 * Игра. Игра - одно из состояний приложения, содержит в себе геймплей и
 * интерфейс Определяет, какой сечас уровень играется
 *
 * @author Esr
 */
public class Game {

		/**
		 * Текущий уровень
		 */
		private Level currentLevel;
		private int currentLevelNumber;
		/**
		 * Геймплей игры
		 */
		private Gameplay gameplay;
		/**
		 * Интерфейс игры
		 */
		private Interface inter;


		public Game() {
		}

		/**
		 * Инициализация игры. Загружаються уровни. Создается геймплей и интерфейс
		 *
		 * @throws SlickException
		 * @throws IOException Файл уровней не может быть открыт
		 * @throws ConfigValueNotFoundException Не найден путь до уровней
		 * @throws Exception
		 */
		public void init() throws SlickException, IOException, ConfigValueNotFoundException, Exception {

				gameplay = new Gameplay();
				inter = new Interface();

				gameplay.init(this);
				inter.init(this);
				
				LevelManager.loadLevelFromFile(Config.toStr("LevelPath"));
				setCurrentLevel(LevelManager.getLevel(0));

		}

		/**
		 * Нажатие мыши или касание экрана
		 *
		 * @param x Координата x
		 * @param y Координата y
		 */
		public void mousePressed(int x, int y) throws Exception {

				if (y > 700) {
						gameplay.mousePressed(x, y);
				} else {
						inter.mousePressed(x, y);
				}

		}

		/**
		 * Получить текущий уровень
		 *
		 * @return Текущий уровень
		 */
		public Level getCurrentLevel() {
				return currentLevel;
		}

		/**
		 * Сменить уровень
		 *
		 * @param num Номер уровня
		 */
		public void changeLevel(int num) throws Exception {
				if (LevelManager.levelAmount() <= num) {
						throw new Exception("Такого уровня нету");
				}
				currentLevelNumber = num;
				setCurrentLevel(LevelManager.getLevel(num));
		}

		public void changeLevelUp() {
				int num = currentLevelNumber + 1;
				if (LevelManager.levelAmount() > num) {
						currentLevelNumber = num;
						setCurrentLevel(LevelManager.getLevel(num));
				}
		}

		public void changeLevelDown() {
				int num = currentLevelNumber - 1;
				if (num >= 0) {
						currentLevelNumber = num;
						setCurrentLevel(LevelManager.getLevel(num));
				}

		}

		/**
		 * Заменить уровень
		 *
		 * @param level Уровень, который будет установлен
		 */
		private void setCurrentLevel(Level level) {
				gameplay.levelChanged();
				inter.levelChanged();
				this.currentLevel = level;
		}

		/**
		 * Получить геймплей
		 *
		 * @return Геймплей
		 */
		public Gameplay getGameplay() {
				return gameplay;
		}

		/**
		 * Получить интерфейс
		 *
		 * @return Интерфейс
		 */
		public Interface getInterface() {
				return inter;
		}

	/**
	 * Номер текущего уроня.
	 * @return Номер текущего уроня.
	 */
		public int getCurrentLevelNumber() {
				return currentLevelNumber;
		}
		
		/**
		 * Функция, вызываемая при смене уровней
		 */
		public void levelComlited() {
				changeLevelUp();
		}
		
		/**
		 * Рестарт уровня
		 */
		public void resetLevel(){
				currentLevel=LevelManager.getLevel(currentLevelNumber);
		}

}
